package edu.gatech.cc.liam.core.rl.pomdp;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import edu.gatech.cc.liam.core.Pair;
import edu.gatech.cc.liam.core.rl.models.Action;
import edu.gatech.cc.liam.core.rl.models.stochasticgame.ConstructedMultiagentRewardFunction;
import edu.gatech.cc.liam.core.rl.models.stochasticgame.DiscreteActionTransitionFunction;
import edu.gatech.cc.liam.core.rl.models.stochasticgame.ConstructedMultiagentRewardFunction.StateJointActionState;


public class ConstructedSingleAgentRewardFunction<StateType, ActionType> {

	ConstructedMultiagentRewardFunction rF = new ConstructedMultiagentRewardFunction(1);
	
	private ArrayList<Action> surroundWithArray(Action a) {
		ArrayList<Action> r = new ArrayList<Action>();
		r.add(a);
		return r;
	}
	
	public ArrayList<Double> reward(String oldState, Action action, String newState) {
		return rF.reward(oldState, surroundWithArray(action), newState);
	}

	// make all rewards range from exactly 0.0 to 1.0
	public void normalizeTempRewards() {
		rF.normalizeTempRewards();
	}	
	// add rewards together and fill in wildcards
	public void finalizeRewards(DiscreteActionTransitionFunction<String> aTransFunc) {
		rF.finalizeRewards(aTransFunc);
	}
	
/**
 * Add a reward to the reward function. Entering a state or jointAction as null will act a wild card.
 * If more than one reward has been entered (because of wild cards) than they will all be added together.
 * If no rewards are given than a reward of zero is given to all players.
 * 
 * @param fromState
 * @param theJoint
 * @param toState
 * @param theReward
 */
	public void addReward(String fromState, Action a, String toState, Double theReward) {
		rF.addReward(fromState, surroundWithArray(a), toState, new Double[]{theReward});
	}
	
	// doesn't display implicit zero rewards
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return rF.toString();
	}
	
	public Double getMaxReward() {
		return rF.getMaxRewards()[0];
	}
	public Double getMinReward() {
		return rF.getMinRewards()[0];
	}
}
